﻿using System;
using System.Text;
using RedBit.OAuthLibrary;

namespace TradeMeSDK
{
    public class TradeMeSearch
    {
        private static void AddSearchCriteria(SearchCriteria criteria, StringBuilder query)
        {
            WebHelper.AddParameter("search_string", criteria.SearchString, query);
            WebHelper.AddParameter("user_region", criteria.Region, query);
            WebHelper.AddParameter("sort_order", criteria.SortOrder, query);
            //if (criteria.StartDate > new DateTime(1000,1,1))
            //    WebHelper.AddParameter("date_from", criteria.StartDate.ToString("u"), query);
            WebHelper.AddParameter("page", criteria.PageNumber, query);
            WebHelper.AddParameter("rows", criteria.Rows, query);
        }

        private static void AddSearchGeneralCriteria(SearchGeneralCriteria criteria, StringBuilder query)
        {
            AddSearchCriteria(criteria, query);
            WebHelper.AddParameter("category", criteria.Category, query);
            if (criteria.OnlyBuyNow)
                WebHelper.AddParameter("buy", "BuyNow", query);
            if (criteria.OnlyPayNow)
                WebHelper.AddParameter("pay", "PayNow", query);
            WebHelper.AddParameter("condition", criteria.Condition, query);
            WebHelper.AddParameter("member_listing", criteria.MemberId, query);
        }

        private static void AddSearchUsedMotorsCriteria(SearchUsedMotorsCriteria criteria, StringBuilder query)
        {
            AddSearchCriteria(criteria, query);

            WebHelper.AddParameter("price_min", criteria.MinPrice, query);
            WebHelper.AddParameter("price_max", criteria.MaxPrice, query);
            WebHelper.AddParameter("make", criteria.Make, query);
            WebHelper.AddParameter("model", criteria.Model, query);
            WebHelper.AddParameter("body_style", criteria.BodyStyle, query);
            WebHelper.AddParameter("doors_min", criteria.MinDoors, query);
            WebHelper.AddParameter("doors_max", criteria.MaxDoors, query);
            WebHelper.AddParameter("transmission", criteria.Transmission, query);
            WebHelper.AddParameter("year_min", criteria.MinYear, query);
            WebHelper.AddParameter("year_max", criteria.MaxYear, query);
            WebHelper.AddParameter("engine_size_min", criteria.MinEngineSize, query);
            WebHelper.AddParameter("engine_size_max", criteria.MaxEngineSize, query);
            WebHelper.AddParameter("odometer_min", criteria.MinOdometer, query);
            WebHelper.AddParameter("odometer_max", criteria.MaxOdometer, query);
            WebHelper.AddParameter("listing_type", criteria.ListingType, query);
        }

        private static void AddSearchNewMotorsCriteria(SearchNewMotorsCriteria criteria, StringBuilder query)
        {
            AddSearchCriteria(criteria, query);

            WebHelper.AddParameter("price_min", criteria.MinPrice, query);
            WebHelper.AddParameter("price_max", criteria.MaxPrice, query);
            WebHelper.AddParameter("make", criteria.Make, query);
            WebHelper.AddParameter("model", criteria.Model, query);
            WebHelper.AddParameter("body_style", criteria.BodyStyle, query);
        }

        private static void AddSearchBoatsCriteria(SearchBoatsCriteria criteria, StringBuilder query)
        {
            AddSearchCriteria(criteria, query);

            WebHelper.AddParameter("price_min", criteria.MinPrice, query);
            WebHelper.AddParameter("price_max", criteria.MaxPrice, query);
            WebHelper.AddParameter("type", criteria.Type, query);
            WebHelper.AddParameter("length_min", criteria.MinLength, query);
        }

        private static void AddSearchMotorBikesCriteria(SearchMotorBikesCriteria criteria, StringBuilder query)
        {
            AddSearchCriteria(criteria, query);

            WebHelper.AddParameter("price_min", criteria.MinPrice, query);
            WebHelper.AddParameter("price_max", criteria.MaxPrice, query);
            WebHelper.AddParameter("make", criteria.Make, query);
            WebHelper.AddParameter("year_min", criteria.MinYear, query);
            WebHelper.AddParameter("year_max", criteria.MaxYear, query);
            WebHelper.AddParameter("engine_size_min", criteria.MinEngineSize, query);
            WebHelper.AddParameter("engine_size_max", criteria.MaxEngineSize, query);
        }

        private static void AddSearchJobsCriteria(SearchJobsCriteria criteria, StringBuilder query)
        {
            WebHelper.AddParameter("search_string", criteria.SearchString, query);
            WebHelper.AddParameter("sort_order", criteria.SortOrder, query);
            WebHelper.AddParameter("salary_min", criteria.MinSalary, query);
            WebHelper.AddParameter("salary_max", criteria.MaxSalary, query);
            WebHelper.AddParameter("region", criteria.Region, query);
            WebHelper.AddParameter("district", criteria.District, query);
            WebHelper.AddParameter("type", criteria.PositionType, query);
            WebHelper.AddParameter("category", criteria.Category, query);
            WebHelper.AddParameter("subcategory", criteria.SubCategory, query);
            WebHelper.AddParameter("page", criteria.PageNumber, query);
            WebHelper.AddParameter("rows", criteria.Rows, query);

        }

        private static void AddSearchResidentialCriteria(SearchResidentialCriteria criteria, StringBuilder query)
        {
            AddSearchCriteria(criteria, query);

            WebHelper.AddParameter("district", criteria.District, query);
            WebHelper.AddParameter("suburb", criteria.Suburb, query);
            WebHelper.AddParameter("price_min", criteria.MinPrice, query);
            WebHelper.AddParameter("price_max", criteria.MaxPrice, query);
            WebHelper.AddParameter("bedrooms_min", criteria.MinBedrooms, query);
            WebHelper.AddParameter("bedrooms_max", criteria.MaxBedrooms, query);
            WebHelper.AddParameter("bathrooms_min", criteria.MinBathrooms, query);
            WebHelper.AddParameter("bathrooms_max", criteria.MaxBathrooms, query);
            WebHelper.AddParameter("area_min", criteria.MinArea, query);
            WebHelper.AddParameter("area_max", criteria.MaxArea, query);
            WebHelper.AddParameter("land_area_min", criteria.MinLandArea, query);
            WebHelper.AddParameter("lad_Area_max", criteria.MaxLandArea, query);
            WebHelper.AddParameter("property_type", criteria.PropertyType, query);
            WebHelper.AddParameter("adjacent_suburbs", criteria.AdjacentSuburbs, query);
        }

        private static void AddSearchCommercialCriteria(SearchCommercialCriteria criteria, StringBuilder query)
        {
            AddSearchCriteria(criteria, query);

            WebHelper.AddParameter("district", criteria.District, query);
            WebHelper.AddParameter("suburb", criteria.Suburb, query);
            WebHelper.AddParameter("price_min", criteria.MinPrice, query);
            WebHelper.AddParameter("price_max", criteria.MaxPrice, query);
            WebHelper.AddParameter("bedrooms_min", criteria.MinBedrooms, query);
            WebHelper.AddParameter("bedrooms_max", criteria.MaxBedrooms, query);
            WebHelper.AddParameter("bathrooms_min", criteria.MinBathrooms, query);
            WebHelper.AddParameter("bathrooms_max", criteria.MaxBathrooms, query);
            WebHelper.AddParameter("area_min", criteria.MinArea, query);
            WebHelper.AddParameter("area_max", criteria.MaxArea, query);
            WebHelper.AddParameter("land_area_min", criteria.MinLandArea, query);
            WebHelper.AddParameter("lad_Area_max", criteria.MaxLandArea, query);
            WebHelper.AddParameter("adjacent_suburbs", criteria.AdjacentSuburbs, query);
            WebHelper.AddParameter("usage", criteria.Usage, query);
        }

        private static void AddSearchRuralCriteria(SearchRuralCriteria criteria, StringBuilder query)
        {
            AddSearchCriteria(criteria, query);

            WebHelper.AddParameter("district", criteria.District, query);
            WebHelper.AddParameter("suburb", criteria.Suburb, query);
            WebHelper.AddParameter("price_min", criteria.MinPrice, query);
            WebHelper.AddParameter("price_max", criteria.MaxPrice, query);
            WebHelper.AddParameter("land_area_min", criteria.MinLandArea, query);
            WebHelper.AddParameter("lad_Area_max", criteria.MaxLandArea, query);
            WebHelper.AddParameter("usage", criteria.Usage, query);
        }

        private static void AddSearchLifestyleCriteria(SearchLifestyleCriteria criteria, StringBuilder query)
        {
            AddSearchCriteria(criteria, query);

            WebHelper.AddParameter("district", criteria.District, query);
            WebHelper.AddParameter("suburb", criteria.Suburb, query);
            WebHelper.AddParameter("price_min", criteria.MinPrice, query);
            WebHelper.AddParameter("price_max", criteria.MaxPrice, query);
            WebHelper.AddParameter("bedrooms_min", criteria.MinBedrooms, query);
            WebHelper.AddParameter("bedrooms_max", criteria.MaxBedrooms, query);
            WebHelper.AddParameter("bathrooms_min", criteria.MinBathrooms, query);
            WebHelper.AddParameter("bathrooms_max", criteria.MaxBathrooms, query);
            WebHelper.AddParameter("area_min", criteria.MinArea, query);
            WebHelper.AddParameter("area_max", criteria.MaxArea, query);
            WebHelper.AddParameter("land_area_min", criteria.MinLandArea, query);
            WebHelper.AddParameter("lad_Area_max", criteria.MaxLandArea, query);
            WebHelper.AddParameter("property_type", criteria.PropertyType, query);
            WebHelper.AddParameter("adjacent_suburbs", criteria.AdjacentSuburbs, query);
            WebHelper.AddParameter("usage", criteria.Usage, query);
        }

        private static void AddSearchFlatmatesCriteria(SearchResidentialCriteria criteria, StringBuilder query)
        {
            AddSearchCriteria(criteria, query);

            WebHelper.AddParameter("district", criteria.District, query);
            WebHelper.AddParameter("suburb", criteria.Suburb, query);
            WebHelper.AddParameter("price_min", criteria.MinPrice, query);
            WebHelper.AddParameter("price_max", criteria.MaxPrice, query);
            WebHelper.AddParameter("adjacent_suburbs", criteria.AdjacentSuburbs, query);
        }


        public void General(SearchGeneralCriteria criteria, Action<BaseEventArgs<SearchResults>> callback)
        {
            StringBuilder query = new StringBuilder();
            AddSearchGeneralCriteria(criteria, query);
            WebHelper.DownloadAndParse(TradeMeConstants.SearchGeneralUrl + "?" + query, callback);
        }

        public void UsedMotors(SearchUsedMotorsCriteria criteria, Action<BaseEventArgs<SearchResults>> callback)
        {
            StringBuilder query = new StringBuilder();
            AddSearchUsedMotorsCriteria(criteria, query);
            WebHelper.DownloadAndParse(TradeMeConstants.SearchUsedMotorsUrl + "?" + query, callback);
        }

        public void NewMotors(SearchNewMotorsCriteria criteria, Action<BaseEventArgs<SearchResults>> callback)
        {
            StringBuilder query = new StringBuilder();
            AddSearchNewMotorsCriteria(criteria, query);
            WebHelper.DownloadAndParse(TradeMeConstants.SearchNewMotorsUrl + "?" + query, callback);
        }

        public void Boats(SearchBoatsCriteria criteria, Action<BaseEventArgs<SearchResults>> callback)
        {
            StringBuilder query = new StringBuilder();
            AddSearchBoatsCriteria(criteria, query);
            WebHelper.DownloadAndParse(TradeMeConstants.SearchBoatsUrl + "?" + query, callback);
        }

        public void MotorBikes(SearchMotorBikesCriteria criteria, Action<BaseEventArgs<SearchResults>> callback)
        {
            StringBuilder query = new StringBuilder();
            AddSearchMotorBikesCriteria(criteria, query);
            WebHelper.DownloadAndParse(TradeMeConstants.SearchMotorBikesUrl + "?" + query, callback);
        }

        public void Jobs(SearchJobsCriteria criteria, Action<BaseEventArgs<SearchResults>> callback)
        {
            StringBuilder query = new StringBuilder();
            AddSearchJobsCriteria(criteria, query);
            WebHelper.DownloadAndParse(TradeMeConstants.SearchJobsUrl + "?" + query, callback);
        }

        public void ResidentialProperties(SearchResidentialCriteria criteria, Action<BaseEventArgs<SearchResults>> callback)
        {
            StringBuilder query = new StringBuilder();
            AddSearchResidentialCriteria(criteria, query);
            WebHelper.DownloadAndParse(TradeMeConstants.SearchResidentialPropertyUrl + "?" + query, callback);
        }

        public void RentalProperties(SearchResidentialCriteria criteria, Action<BaseEventArgs<SearchResults>> callback)
        {
            StringBuilder query = new StringBuilder();
            AddSearchResidentialCriteria(criteria, query);
            WebHelper.DownloadAndParse(TradeMeConstants.SearchRentalPropertyUrl + "?" + query, callback);
        }

        public void OpenHomes(SearchResidentialCriteria criteria, Action<BaseEventArgs<SearchResults>> callback)
        {
            StringBuilder query = new StringBuilder();
            AddSearchResidentialCriteria(criteria, query);
            WebHelper.DownloadAndParse(TradeMeConstants.SearchOpenHomesUrl + "?" + query, callback);
        }

        public void CommercialProperty(SearchCommercialCriteria criteria, Action<BaseEventArgs<Properties>> callback)
        {
            StringBuilder query = new StringBuilder();
            AddSearchCommercialCriteria(criteria, query);
            WebHelper.DownloadAndParse(TradeMeConstants.SearchCommercialPropertyUrl + "?" + query, callback);
        }

        public void CommercialLease(SearchCommercialCriteria criteria, Action<BaseEventArgs<Properties>> callback)
        {
            StringBuilder query = new StringBuilder();
            AddSearchCommercialCriteria(criteria, query);
            WebHelper.DownloadAndParse(TradeMeConstants.SearchCommercialLeaseUrl + "?" + query, callback);
        }

        public void Rural(SearchRuralCriteria criteria, Action<BaseEventArgs<Properties>> callback)
        {
            StringBuilder query = new StringBuilder();
            AddSearchRuralCriteria(criteria, query);
            WebHelper.DownloadAndParse(TradeMeConstants.SearchCommercialLeaseUrl + "?" + query, callback);
        }

        public void Lifestyle(SearchLifestyleCriteria criteria, Action<BaseEventArgs<Properties>> callback)
        {
            StringBuilder query = new StringBuilder();
            AddSearchLifestyleCriteria(criteria, query);
            WebHelper.DownloadAndParse(TradeMeConstants.SearchLifestylePropertyUrl + "?" + query, callback);
        }

        public void Retirement(SearchResidentialCriteria criteria, Action<BaseEventArgs<Properties>> callback)
        {
            StringBuilder query = new StringBuilder();
            AddSearchResidentialCriteria(criteria, query);
            WebHelper.DownloadAndParse(TradeMeConstants.SearchRetirementUrl + "?" + query, callback);
        }

        public void Flatmates(SearchResidentialCriteria criteria, Action<BaseEventArgs<SearchResults>> callback)
        {
            StringBuilder query = new StringBuilder();
            AddSearchFlatmatesCriteria(criteria, query);
            WebHelper.DownloadAndParse(TradeMeConstants.SearchFlatmatesUrl + "?" + query, callback);
        }

        /// <summary>
        /// Retrieves the details of a single listing identified by the Trade Me listing id.
        /// </summary>
        public void Listing(int listingId, Action<BaseEventArgs<ListedItemDetail>> callback)
        {
            string url = TradeMeConstants.ListingsUrl + listingId + ".json";
            WebHelper.DownloadAndParse(url, callback);
        }

        public void LoggedOnListing(int listingId, Action<BaseEventArgs<ListedItemDetail>> callback)
        {
            string url = TradeMeConstants.ListingsUrl + listingId + ".json";
            WebHelper.DownloadAndParseProtected(url, callback);
        }
    }
}